package com.xingjiejian.leetcode.easy;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 给定一个只包括 '('，')'，'{'，'}'，'['，']' 的字符串，判断字符串是否有效。
 * 有效字符串需满足：
 *    1.左括号必须用相同类型的右括号闭合。
 *    2.左括号必须以正确的顺序闭合。
 * 注意：空字符串可被认为是有效字符串。
 *
 * @author XingJiejian
 * @date 2019/5/20 0020
 */
public class ValidParentheses {
    private Map<Character,Character> mappings;

    public ValidParentheses() {
        this.mappings = new HashMap<>();
        this.mappings.put('}','{');
        this.mappings.put(')','(');
        this.mappings.put(']','[');
    }

    /**
     * 检验字符串是否括号正确闭合
     *
     * 解题思路：使用“栈”处理
     *
     * @param s
     * @return
     */
    public boolean isValid(String s) {
        //创建存储前括号的栈
        Stack<Character> stack = new Stack<> ();
        for (int i = 0; i < s.length(); i++) {
            //遍历提取字符
            char c = s.charAt(i);
            //如果是后括号
            if(this.mappings.containsKey(c)){
                //提取并删除当前栈顶元素，如果栈是空的给一个虚拟值“#”
                char topElement = stack.empty() ? '#' : stack.pop();
                //判断如果栈顶元素不是与当前元素相对应的括号，则直接返回false
                if (topElement!= this.mappings.get(c)){
                    return false;
                }
            }else{
                //如果不是后括号，则加入栈
                stack.push(c);
            }
        }
        //如果循环结束，栈为空，说明所有括号都正确对应
        return stack.isEmpty();
    }
}

/*
算法
初始化栈 S。
一次处理表达式的每个括号。
如果遇到开括号，我们只需将其推到栈上即可。这意味着我们将稍后处理它，让我们简单地转到前面的 子表达式。
如果我们遇到一个闭括号，那么我们检查栈顶的元素。如果栈顶的元素是一个 相同类型的 左括号，
那么我们将它从栈中弹出并继续处理。否则，这意味着表达式无效。

如果到最后我们剩下的栈中仍然有元素，那么这意味着表达式无效。
 */